/**
 * page基类封装，实现预加载
 */

import Navigator from "./Navigator";

export default class CommonPage {
  constructor(...args) {
    /**
     * 这边加基类实例化限制，小程序编译会出错，故先注释了
     */
    // if (new.target === CommonPage) {
    //   throw new Error("the CommonPage class can't be instantiated!")
    // }
    
    if (args.length) {
      const name = args[0].clazzName;
      // console.log("ClazzName:", name)
      if (name) {
        this.data = { clazzName: name };
        Navigator.putPage(name, this);
      }
    }
  }

  $init(originData) {
    Object.assign(this.data = this.data ? this.data : {}, originData);
    this.$origin = JSON.parse(JSON.stringify(this.data));
    Object.freeze(this.$origin);
  }
 
  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {
    // console.log("CommonPage卸载：", this.data)
    if (this.data.clazzName) {
      // console.log("Unload page:", this.data.clazzName)
      let clazz = Navigator.getPage(this.data.clazzName);
      if (!clazz || !clazz.$origin) {
        console.error('请先在页面的constructor方法中注入init(data)，以避免出现不必要的错误');
        return;
      }
      clazz.data = JSON.parse(JSON.stringify(clazz.$origin));
    }
  }
  /**
   * 预加载专用,解决上下文不一致
   * @data  data对象
   */
  $setData = function (data) {
    if (this.setData) {
      this.setData(data);
    } else {
      Object.assign(this.data = this.data ? this.data : {}, data);
    }
  };

  /**
   * page跳转接口,需要在跳转页面定义$onNavigator(query)函数
   * @path page路由地址，相对地址
   * @query 需要传递的参数，对象类型
   * @clazzName 需要跳转的页面类名
   */
  $route = function ({ path = '', query = {}, clazzName = '' }) {
    let args = '';
    if (Object.keys(query).length) {
      args = '?';
      for (let i in query) {
        if (query.hasOwnProperty(i)) {
          args += i + '=' + query[i] + '&';
        }
      }
      args = args.substring(0, args.length - 1);
    }
    
    let clazz = Navigator.getPage(clazzName);
    if (clazz && clazz.$onNavigator) {
      console.debug("预加载路由：", clazzName, args)
      clazz.$onNavigator && clazz.$onNavigator(query);
      setTimeout(() => {
        wx.navigateTo({ url: `${path + args}` });
      }, 150);
    } else {
      console.debug("普通路由：", clazzName, args)
      wx.navigateTo({ url: `${path + args}` });
    }
  };

  /**
   * 被调用页面的$onNavigator()会调用put，完成预加载动作
   * @key 预加载信息的键
   * @fun 回调函数，预加载信息的处理函数
   * @args 回调函数参数
   */
  $put = function (key = '', fun = null, args = null) {
    if (key && fun) {
      CommonPage.prototype._pageValues[`${this.data.clazzName}?${key}`] = CommonPage._$delay(this, fun, args);
    }
  };

  /**
   * 根据key获取预加载数据，
   * 若是put中传入的回调执行了$resolve，需调用then方法获取数据
   */
  $take = function (key = '') {
    if (key) {
      const promise = CommonPage.prototype._pageValues[`${this.data.clazzName}?${key}`];
      delete CommonPage.prototype._pageValues[`${this.data.clazzName}?${key}`];
      return promise;
    }
    return null;
  };

  static _$delay(context, cb, args) {
    return new Promise((resolve, reject) => {
      context.resolve = resolve;
      context.reject = reject;
      CommonPage.prototype.currentPageContext = context;
      cb && cb(args, resolve, reject);
    });
  }

  $resolve = function (data) {
    const context = CommonPage.prototype.currentPageContext;
    !!context && !!context.resolve && context.resolve(data);
    CommonPage.prototype.currentPageContext = null;
  };

  $reject = function (data, error) {
    const context = CommonPage.prototype.currentPageContext;
    !!context && !!context.reject && !!context.reject(data, error);
    CommonPage.prototype.currentPageContext = null;
  };

  /**
  * 生命周期函数--监听页面加载
  */
  onLoad(options) {

  }

  // /**
  //  * 生命周期函数--监听页面初次渲染完成
  //  */
  // onReady() {

  // }

  // /**
  //  * 生命周期函数--监听页面显示
  //  */
  onShow() {

  }

  // /**
  //  * 生命周期函数--监听页面隐藏
  //  */
  // onHide() {

  // }
  // /**
  //  * 页面相关事件处理函数--监听用户下拉动作
  //  */
  // onPullDownRefresh() {

  // }

  // /**
  //  * 页面上拉触底事件的处理函数
  //  */
  // onReachBottom() {

  // }

  // /**
  //  * 用户点击右上角分享
  //  */
  onShareAppMessage() {

  }

}

CommonPage.prototype._pageValues = {};
CommonPage.prototype.currentPageContext = null;